package com.traffic.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.traffic.constant.Const;
import com.traffic.constant.Status;
import com.traffic.entity.Resource;
import com.traffic.model.ApiResponse;
import com.traffic.service.ResourceService;
import com.traffic.util.JwtUtil;
import io.minio.MinioClient;
import io.minio.policy.PolicyType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: KingRainGrey
 * Date: 2020/9/7
 */
@Api(tags = "文件上传相关接口")
@RestController
@RequestMapping("/minio")
@Slf4j
public class MinioController {
    @Value("${minio.endpoint}")
    private String ENDPOINT;
    @Value("${minio.bucketName}")
    private String BUCKET_NAME;
    @Value("${minio.accessKey}")
    private String ACCESS_KEY;
    @Value("${minio.secretKey}")
    private String SECRET_KEY;

    @Autowired
    private ResourceService resourceService;

    @Autowired
    private JwtUtil jwtUtil;


    @ApiOperation(value = "【图片上传】",
            notes = "【account】用户手机号,【kind】管理员传0，用户传1,【type】管理员可传0[启动页]1[logo]2[消息配图]，用户可传0[头像]1[反馈意见配图]")
    @PostMapping("/headImg/upload")
    public ApiResponse headImgUpload(@RequestParam MultipartFile file, @RequestParam String account,
                              @RequestParam Integer kind, @RequestParam Integer type) {
        // token验证
//        if (!jwtUtil.check(account) && !jwtUtil.confirm(account)) {
//            return ApiResponse.ofStatus(Status.TOKEN_ERROR);
//        }
        // 参数验证
        if (kind < 0 || kind > 1 || type < 0 || type > 2) {
            return ApiResponse.ofStatus(Status.PARAM_ERROR);
        }

        if (ObjectUtil.isNull(file)) {
            return ApiResponse.ofStatus(Status.COMMON_ERROR);
        }

        try {
//            MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
//            boolean isExist = minioClient.bucketExists(BUCKET_NAME);
//            if (isExist) {
//                log.info("【存储桶已经存在!】");
//            }else {
//                minioClient.makeBucket(BUCKET_NAME);
//                minioClient.setBucketPolicy(BUCKET_NAME, "*.*", PolicyType.READ_ONLY);
//            }
            MinioClient minioClient = create();
            if (ObjectUtil.isNull(minioClient)) {
                return ApiResponse.ofStatus(Status.COMMON_ERROR);
            }
            Resource resource = save(file, minioClient, account, kind, type);
//            String filename = ("" + System.currentTimeMillis());
//            // String filename = file.getOriginalFilename();
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//            // 设置存储对象名称
//            String objectName = sdf.format(new Date()) + "/" + filename;
//            // 使用putObject上传一个文件到存储桶中
//            minioClient.putObject(BUCKET_NAME, objectName, file.getInputStream(), file.getContentType());
//            log.info("【文件上传成功!】");
//            Resource resource = Resource.builder().name(objectName).url(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName).build();
//            resourceService.save(resource, account, kind, type);
//            if (ObjectUtil.isNotEmpty(resource.getId())) {
//                return ApiResponse.ofStatus(Status.OK, resource);
//            }
            if (ObjectUtil.isNotNull(resource)) {
                return ApiResponse.ofStatus(Status.OK, resource);
            }
        }catch (Exception e){
            log.info("【文件上传失败】:{}", e.getMessage());
        }
        return ApiResponse.ofStatus(Status.UNKNOWN_ERROR);
    }



    @ApiOperation(value = "【图片上传】",
            notes = "【account】用户手机号,【kind】管理员传0，用户传1,【type】管理员可传0[启动页]1[logo]2[消息配图]，用户可传0[头像]1[反馈意见配图]")
    @PostMapping("/upload")
    public ApiResponse upload(@RequestParam MultipartFile file, @RequestParam String account,
                              @RequestParam Integer kind, @RequestParam Integer type) {
        // token验证
//        if (!jwtUtil.check(account) && !jwtUtil.confirm(account)) {
//            return ApiResponse.ofStatus(Status.TOKEN_ERROR);
//        }
        // 参数验证
        if (kind < 0 || kind > 1 || type < 0 || type > 2) {
            return ApiResponse.ofStatus(Status.PARAM_ERROR);
        }

        if (ObjectUtil.isNull(file)) {
            return ApiResponse.ofStatus(Status.COMMON_ERROR);
        }

        try {
//            MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
//            boolean isExist = minioClient.bucketExists(BUCKET_NAME);
//            if (isExist) {
//                log.info("【存储桶已经存在!】");
//            }else {
//                minioClient.makeBucket(BUCKET_NAME);
//                minioClient.setBucketPolicy(BUCKET_NAME, "*.*", PolicyType.READ_ONLY);
//            }
            MinioClient minioClient = create();
            if (ObjectUtil.isNull(minioClient)) {
                return ApiResponse.ofStatus(Status.COMMON_ERROR);
            }
            Resource resource = save(file, minioClient, account, kind, type);
//            String filename = ("" + System.currentTimeMillis());
//            // String filename = file.getOriginalFilename();
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//            // 设置存储对象名称
//            String objectName = sdf.format(new Date()) + "/" + filename;
//            // 使用putObject上传一个文件到存储桶中
//            minioClient.putObject(BUCKET_NAME, objectName, file.getInputStream(), file.getContentType());
//            log.info("【文件上传成功!】");
//            Resource resource = Resource.builder().name(objectName).url(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName).build();
//            resourceService.save(resource, account, kind, type);
//            if (ObjectUtil.isNotEmpty(resource.getId())) {
//                return ApiResponse.ofStatus(Status.OK, resource);
//            }
            if (ObjectUtil.isNotNull(resource)) {
                return ApiResponse.ofStatus(Status.OK, resource.getId());
            }
        }catch (Exception e){
            log.info("【文件上传失败】:{}", e.getMessage());
        }
        return ApiResponse.ofStatus(Status.UNKNOWN_ERROR);
    }

    @ApiOperation(value = "【多张图片上传】",
            notes = "【account】用户手机号,【kind】管理员传0，用户传1,【type】管理员可传0[启动页]1[logo]2[消息配图]，用户可传0[头像]1[反馈意见配图]")
    @PostMapping("/more/upload")
    public ApiResponse uploadMore(@RequestParam MultipartFile file1,
                                  MultipartFile file2,
                                  MultipartFile file3,
                                  @RequestParam String account,
                                  @RequestParam Integer kind, @RequestParam Integer type) {

        // 参数验证
        if (kind < 0 || kind > 1 || type < 0 || type > 2) {
            return ApiResponse.ofStatus(Status.PARAM_ERROR);
        }

//        if (ObjectUtil.isNull(file1) || ObjectUtil.isNull(file2) || ObjectUtil.isNull(file3)) {
//            return ApiResponse.ofStatus(Status.COMMON_ERROR);
//        }

        try {
//            MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
//            boolean isExist = minioClient.bucketExists(BUCKET_NAME);
//            if (isExist) {
//                log.info("【存储桶已经存在!】");
//            }else {
//                minioClient.makeBucket(BUCKET_NAME);
//                minioClient.setBucketPolicy(BUCKET_NAME, "*.*", PolicyType.READ_ONLY);
//            }
            MinioClient minioClient = create();
            if (ObjectUtil.isNull(minioClient)) {
                return ApiResponse.ofStatus(Status.COMMON_ERROR);
            }

            List<String> paths = new ArrayList<>();
            List<MultipartFile> files = new ArrayList<>();
            files.add(file1);
            files.add(file2);
            files.add(file3);
            for (MultipartFile file:files) {
                if (ObjectUtil.isNotNull(file) && file.getSize() > 0) {
                    Resource resource = save(file, minioClient, account, kind, type);
                    if (ObjectUtil.isNull(resource)) {
                        return ApiResponse.ofStatus(Status.COMMON_ERROR);
                    }else {
                        paths.add(resource.getUrl());
                    }
                }
            }

            return ApiResponse.ofStatus(Status.OK, paths);

        }catch (Exception e){
            log.info("【文件上传失败】:{}", e.getMessage());
        }
        return ApiResponse.ofStatus(Status.UNKNOWN_ERROR);
    }

    private MinioClient create() {
        try {
            MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
            boolean isExist = minioClient.bucketExists(BUCKET_NAME);
            if (isExist) {
                log.info("【存储桶已经存在!】");
            }else {
                minioClient.makeBucket(BUCKET_NAME);
                minioClient.setBucketPolicy(BUCKET_NAME, "*.*", PolicyType.READ_ONLY);
            }
            return minioClient;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private Resource save(MultipartFile file, MinioClient minioClient, String account, Integer kind, Integer type) {
        try {
            String filename = ("" + System.currentTimeMillis()) + file.getOriginalFilename();

            // String filename = file.getOriginalFilename();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // 设置存储对象名称
            String objectName = sdf.format(new Date()) + "/" + filename;
            // 使用putObject上传一个文件到存储桶中
            minioClient.putObject(BUCKET_NAME, objectName, file.getInputStream(), file.getContentType());
            log.info("【文件上传成功!】");
            Resource resource = Resource.builder().name(objectName).url(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName).build();
            resourceService.save(resource, account, kind, type);
            if (ObjectUtil.isNotEmpty(resource.getId())) {
                return resource;
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @ApiOperation(value = "【图片文件删除】", notes = "需添加token,管理员权限")
    @DeleteMapping("/{id}")
    public ApiResponse delete(@PathVariable Long id) {
        // token验证
        if (!jwtUtil.confirm(jwtUtil.getAccount(Const.TAG_ADMIN))) {
            return ApiResponse.ofStatus(Status.TOKEN_ERROR);
        }
        String objectName = resourceService.get(id).getName();
        try {
            // minio删除图片资源
            MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
            minioClient.removeObject(BUCKET_NAME, objectName);
            // 数据库记录删除
            resourceService.delete(id);
            return ApiResponse.ofStatus(Status.OK);
        }catch (Exception e) {
            log.info("【文件删除失败】:{}", e.getMessage());
        }
        return ApiResponse.ofStatus(Status.COMMON_ERROR);
    }

    @ApiOperation(value = "【图片文件URL获取】")
    @GetMapping("/{id}")
    public ApiResponse getUrl(@PathVariable Long id) {
        String url = resourceService.get(id).getUrl();
        if (StrUtil.isNotEmpty(url)) {
            return ApiResponse.ofStatus(Status.OK, url);
        }
        return ApiResponse.ofStatus(Status.COMMON_ERROR);
    }

    @ApiOperation(value = "【收藏图标获取】")
    @GetMapping("/geticon")
    public ApiResponse getIcons() {
        List<Resource> Rlist = resourceService.getCollectIcons();

        return ApiResponse.ofStatus(Status.OK, Rlist);

        //return ApiResponse.ofStatus(Status.COMMON_ERROR);
    }


    @ApiOperation(value = "【收藏地点图标上传】",
            notes = "【account】用户手机号,【kind】管理员传0【type】管理员传3[收藏地点logo]4[过期收藏logo]")
    @PostMapping("/updateicon")
    public ApiResponse updateicon(@RequestParam MultipartFile file, @RequestParam String account,
                              @RequestParam Integer kind, @RequestParam Integer type,@RequestParam Integer oid) {
        // token验证
//        if (!jwtUtil.check(account) && !jwtUtil.confirm(account)) {
//            return ApiResponse.ofStatus(Status.TOKEN_ERROR);
//        }
//        // 参数验证
//        if (kind < 0 || kind > 1 || type < 0 || type > 2) {
//            return ApiResponse.ofStatus(Status.PARAM_ERROR);
//        }

        try {
//            MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
//            boolean isExist = minioClient.bucketExists(BUCKET_NAME);
//            if (isExist) {
//                log.info("【存储桶已经存在!】");
//            }else {
//                minioClient.makeBucket(BUCKET_NAME);
//                minioClient.setBucketPolicy(BUCKET_NAME, "*.*", PolicyType.READ_ONLY);
//            }
            MinioClient minioClient = create();
            if (ObjectUtil.isNull(minioClient)) {
                return ApiResponse.ofStatus(Status.COMMON_ERROR);
            }
//            String filename = file.getOriginalFilename();
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//            // 设置存储对象名称
//            String objectName = sdf.format(new Date()) + "/" + filename;
//            // 使用putObject上传一个文件到存储桶中
//            minioClient.putObject(BUCKET_NAME, objectName, file.getInputStream(), file.getContentType());
//            log.info("【文件上传成功!】");
//            Resource resource = Resource.builder().name(objectName).url(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName).build();
//            resourceService.save(resource, account, kind, type);
            Resource resource = save(file, minioClient, account, kind, type);

            if (ObjectUtil.isNotEmpty(resource.getId())) {

                UpdateWrapper<Resource> wrapper = new UpdateWrapper<>();

                resourceService.update(wrapper.set("type",4).eq("id",oid));
                return ApiResponse.ofStatus(Status.OK, resource);
            }
        }catch (Exception e){
            log.info("【文件上传失败】:{}", e.getMessage());
        }
        return ApiResponse.ofStatus(Status.UNKNOWN_ERROR);
    }


}
